/*
@(#)WebLogAspect   2024-01-15
 
Copyright (c) 2011-2024 杭州湖畔网络技术有限公司 
保留所有权利 
本软件为杭州湖畔网络技术有限公司所有及包含机密信息，须遵守其相关许可证条款进行使用。
Copyright (c) 2011-2024 HUPUN Network Technology CO.,LTD.
All rights reserved.
This software is the confidential and proprietary information of HUPUN
Network Technology CO.,LTD("Confidential Information").  You shall not
disclose such Confidential Information and shall use it only in
accordance with the terms of the license agreement you entered into with HUPUN.
Website：http://www.hupun.com
*/
package org.obp.log.aspect;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.CodeSignature;
import org.obp.core.result.ApiResult;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.LinkedHashMap;

/**
 * @author: Jackey 2024/1/15
 */
@Slf4j
@Aspect
@Component
public class WebLogAspect {


    @Value("${sa-token.token-name:auth-token}")
    private String tokenHeader;

    @Pointcut("execution(public * org.obp.*.controller..*.*(..))")
    public void webLog() {
    }

    @Around("webLog()")
    public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {

        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        long startTime = System.currentTimeMillis();
        Object result = null;
        try {
            result = proceedingJoinPoint.proceed();
            return result;

        } finally {
            if (result instanceof ApiResult) {
                ApiResult<?> apiResult = (ApiResult<?>) result;
                apiResult.setTraceId(MDC.get(ApiResult.TRACE_ID));
            }
            long endTime = System.currentTimeMillis();

            String requestMethod = request.getMethod();
            String requestUri = request.getRequestURI();
            String costTime = (endTime - startTime) + "ms";
            String jsonParams = getParams(proceedingJoinPoint);

            String token = request.getHeader(tokenHeader);

            log.info("Method: {}, URL: {}, Token: {}, Time: {}, Params: {}",
                    requestMethod, requestUri, token, costTime, jsonParams);
        }
    }

    /**
     * 获取参数名和参数值
     *
     * @param joinPoint
     * @return 返回JSON结构字符串
     */
    public String getParams(JoinPoint joinPoint) {
        LinkedHashMap<String, Object> map = new LinkedHashMap<>();
        Object[] values = joinPoint.getArgs();
        String[] names = ((CodeSignature) joinPoint.getSignature()).getParameterNames();
        for (int i = 0; i < names.length; i++) {
            if (values[i] instanceof HttpServletRequest
                    || values[i] instanceof HttpServletResponse
                    || values[i] instanceof MultipartFile) continue;
            map.put(names[i], values[i]);
        }
        return JSONObject.toJSONString(map);
    }

}